#include "hal_data.h"
#include <stdio.h>
FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER

fsp_err_t err = FSP_SUCCESS;
volatile bool uart_send_complete_flag = false;
void user_uart_callback (uart_callback_args_t * p_args)
{
    if(p_args->event == UART_EVENT_TX_COMPLETE)
    {
        uart_send_complete_flag = true;
    }
}

#ifdef __GNUC__                                 //串口重定向
    #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
    #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif


PUTCHAR_PROTOTYPE
{
        err = R_SCI_UART_Write(&g_uart9_ctrl, (uint8_t *)&ch, 1);
        if(FSP_SUCCESS != err) __BKPT();
        while(uart_send_complete_flag == false){}
        uart_send_complete_flag = false;
        return ch;
}

int _write(int fd,char *pBuffer,int size)
{
    for(int i=0;i<size;i++)
    {
        __io_putchar(*pBuffer++);
    }
    return size;
}

volatile uint32_t up1_capture_time = 0;     // 用于存储第一次上升沿捕获的时间
volatile uint32_t down_capture_time = 0;     // 用于存储第一次上升沿捕获的时间
volatile uint32_t up2_capture_time = 0;     // 用于存储第二次上升沿捕获的时间
volatile uint32_t pulse_width = 0;          // 用于存储脉冲宽度
volatile uint32_t pulse_period = 0;         // 用于存储脉冲周期
volatile double duty_cycle = 0;           // 用于存储正占空比
volatile double frequency = 0;            // 用于存储频率

void gpt2_callback(timer_callback_args_t *p_args)
{
    /* TODO: add your own code here */
    if ((TIMER_EVENT_CAPTURE_B == p_args->event))  // 捕获事件
    {
        bsp_io_level_t p_port_value_port_102;
        // 读取端口电平状态，如果是低电平则发生的是下降沿，高电平则是上升沿
        R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_02, &p_port_value_port_102);

        // 获取当前定时器的时钟频率和周期
        timer_info_t info;
        (void) R_GPT_InfoGet(&g_timer2_ctrl, &info);
        uint64_t clock_frequency = info.clock_frequency; // 定时器时钟频率
        uint32_t current_period_counts = info.period_counts; // 定时器周期

        uint32_t current_time = p_args->capture; // 获取当前捕获时间（计数值）

        if (p_port_value_port_102 == BSP_IO_LEVEL_HIGH) // 上升沿
        {
            // 记录第一次和第二次上升沿的时间戳
            up1_capture_time=up2_capture_time;
            up2_capture_time=current_time;

            // 计算脉冲周期：从第一次到第二次上升沿的时间差
            if(up2_capture_time>=up1_capture_time)
                pulse_period = (up2_capture_time-up1_capture_time);
            else
                pulse_period = (current_period_counts -up1_capture_time) + up2_capture_time;
            // 计算频率：频率 = 时钟频率 / 脉冲周期
            frequency  =(double) (clock_frequency/pulse_period);

            // 计算脉冲宽度：从下降沿到第二次上升沿的时间差
            if(up2_capture_time>=down_capture_time)
                pulse_width=up2_capture_time-down_capture_time;
            else
                pulse_width=(current_period_counts -down_capture_time) + up2_capture_time;
            // 计算占空比：占空比 = 脉冲宽度 / 脉冲周期
            duty_cycle = 100.0f-(pulse_width*100 / (double)pulse_period);

        }
        else // 下降沿
        {
            // 更新下降沿的捕获时间
            down_capture_time=current_time;
        }

    }
}




/*******************************************************************************************************************//**
 * main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used.  This function
 * is called by main() when no RTOS is used.
 **********************************************************************************************************************/
void hal_entry(void)
{
    /* TODO: add your own code here */

    fsp_err_t err = FSP_SUCCESS;
    /* Initializes the module. */
    err = R_GPT_Open(&g_timer5_ctrl, &g_timer5_cfg);
    /* Handle any errors. This function should be defined by the user. */
    assert(FSP_SUCCESS == err);

    /* Start the timer. */
    (void) R_GPT_Start(&g_timer5_ctrl);
    R_BSP_SoftwareDelay (20, BSP_DELAY_UNITS_MILLISECONDS);


    err = R_GPT_PeriodSet(&g_timer5_ctrl, 6000);//频率
   assert(FSP_SUCCESS == err);
   R_BSP_SoftwareDelay (20, BSP_DELAY_UNITS_MILLISECONDS);//不加延时可能会设置不成功

   err = R_GPT_DutyCycleSet(&g_timer5_ctrl, 1500, GPT_IO_PIN_GTIOCA);//占空比
   assert(FSP_SUCCESS == err);
   err = R_GPT_DutyCycleSet(&g_timer5_ctrl, 4500, GPT_IO_PIN_GTIOCB);//占空比
   assert(FSP_SUCCESS == err);
   R_BSP_SoftwareDelay (20, BSP_DELAY_UNITS_MILLISECONDS);

//   err = R_GPT_Close(&g_timer5_ctrl);
//   assert(FSP_SUCCESS == err);
//   R_BSP_SoftwareDelay (20, BSP_DELAY_UNITS_MILLISECONDS);


   /* Open the transfer instance with initial configuration. */
   err = R_SCI_UART_Open(&g_uart9_ctrl, &g_uart9_cfg);
   assert(FSP_SUCCESS == err);

   printf("hello\n");

   /* Initializes the module. */
   err = R_GPT_Open(&g_timer2_ctrl, &g_timer2_cfg);
   /* Handle any errors. This function should be defined by the user. */
   assert(FSP_SUCCESS == err);
   /* Start the timer. */
   (void) R_GPT_Start(&g_timer2_ctrl);

   (void) R_GPT_Enable(&g_timer2_ctrl);
   R_BSP_SoftwareDelay (20, BSP_DELAY_UNITS_MILLISECONDS);

   while(1)
   {
       printf("frequency=%.2f,duty cycle=%.2f\n",frequency,duty_cycle);
       duty_cycle = 0;  // 重置占空比
       frequency = 0;   // 重置频率
       R_BSP_SoftwareDelay (200, BSP_DELAY_UNITS_MILLISECONDS);

   }




#if BSP_TZ_SECURE_BUILD
    /* Enter non-secure code */
    R_BSP_NonSecureEnter();
#endif
}

/*******************************************************************************************************************//**
 * This function is called at various points during the startup process.  This implementation uses the event that is
 * called right before main() to set up the pins.
 *
 * @param[in]  event    Where at in the start up process the code is currently at
 **********************************************************************************************************************/
void R_BSP_WarmStart(bsp_warm_start_event_t event)
{
    if (BSP_WARM_START_RESET == event)
    {
#if BSP_FEATURE_FLASH_LP_VERSION != 0

        /* Enable reading from data flash. */
        R_FACI_LP->DFLCTL = 1U;

        /* Would normally have to wait tDSTOP(6us) for data flash recovery. Placing the enable here, before clock and
         * C runtime initialization, should negate the need for a delay since the initialization will typically take more than 6us. */
#endif
    }

    if (BSP_WARM_START_POST_C == event)
    {
        /* C runtime environment and system clocks are setup. */

        /* Configure pins. */
        R_IOPORT_Open (&IOPORT_CFG_CTRL, &IOPORT_CFG_NAME);

#if BSP_CFG_SDRAM_ENABLED

        /* Setup SDRAM and initialize it. Must configure pins first. */
        R_BSP_SdramInit(true);
#endif
    }
}

#if BSP_TZ_SECURE_BUILD

FSP_CPP_HEADER
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ();

/* Trustzone Secure Projects require at least one nonsecure callable function in order to build (Remove this if it is not required to build). */
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ()
{

}
FSP_CPP_FOOTER

#endif
